package com.edu.exam.entity.grading;

import com.edu.exam.enums.common.WorkflowStatus;
import com.edu.exam.enums.core.BaseEnum;
import com.edu.exam.enums.grading.GradeLogLevel;
import com.edu.exam.enums.grading.GradeOperationResult;
import com.edu.exam.enums.grading.GradeOperationSource;
import com.edu.exam.enums.grading.GradeOperationType;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 成绩录入日志实体类
 * 所属模块：B-06 成绩管理模块
 *
 * <p>成绩录入日志实体用于记录成绩录入的所有操作历史，包含
 * 操作记录、变更追踪、版本控制、审核轨迹等。确保成绩数据的完整审计追溯。</p>
 *
 * <p>核心功能：
 * - 操作记录：记录所有成绩相关的操作行为
 * - 变更追踪：追踪成绩数据的变更历史
 * - 版本控制：维护成绩数据的版本信息
 * - 审核轨迹：记录审核流程的完整路径
 * - 异常记录：记录异常情况和处理结果</p>
 *
 * @author 系统生成
 * @version 1.0
 * @since 2025-11-10
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@EntityListeners(AuditingEntityListener.class)
public class GradeEntryLog {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 成绩录入ID
     *
     * <p>关联的成绩录入记录ID。</p>
     */
    @Column(name = "grade_entry_id", nullable = false)
    private Long gradeEntryId;

    /**
     * 学生ID
     *
     * <p>关联学生的唯一标识符。</p>
     */
    @Column(name = "student_id", nullable = false, length = 50)
    private String studentId;

    /**
     * 课程ID
     *
     * <p>关联课程的唯一标识符。</p>
     */
    @Column(name = "course_id", nullable = false, length = 50)
    private String courseId;

    /**
     * 操作类型
     * <p>日志记录的操作类型。
     * 使用GradeOperationType枚举管理所有操作类型</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "operation_type", nullable = false, length = 30)
    private GradeOperationType operationType;

    /**
     * 操作时间
     *
     * <p>操作发生的时间。</p>
     */
    @Column(name = "operation_time", nullable = false)
    private LocalDateTime operationTime;

    /**
     * 操作员ID
     *
     * <p>执行操作的用户ID。</p>
     */
    @Column(name = "operator_id", nullable = false, length = 50)
    private String operatorId;

    /**
     * 操作员姓名
     *
     * <p>执行操作的用户姓名。</p>
     */
    @Column(name = "operator_name", length = 100)
    private String operatorName;

    /**
     * 操作前值
     *
     * <p>操作前的分数值。</p>
     */
    @Column(name = "before_value", precision = 10, scale = 2)
    private BigDecimal beforeValue;

    /**
     * 操作后值
     *
     * <p>操作后的分数值。</p>
     */
    @Column(name = "after_value", precision = 10, scale = 2)
    private BigDecimal afterValue;

    /**
     * 变更原因
     *
     * <p>数据变更的原因说明。</p>
     */
    @Column(name = "change_reason", length = 500)
    private String changeReason;

    /**
     * 操作备注
     *
     * <p>操作的详细备注信息。</p>
     */
    @Column(name = "operation_comment", columnDefinition = "TEXT")
    private String operationComment;

    /**
     * IP地址
     *
     * <p>操作发起的IP地址。</p>
     */
    @Column(name = "ip_address", length = 50)
    private String ipAddress;

    /**
     * 用户代理
     *
     * <p>操作发起的客户端信息。</p>
     */
    @Column(name = "user_agent", length = 500)
    private String userAgent;

    /**
     * 会话ID
     *
     * <p>操作所属的会话ID。</p>
     */
    @Column(name = "session_id", length = 100)
    private String sessionId;

    /**
     * 批次ID
     *
     * <p>批量操作的批次标识符。</p>
     */
    @Column(name = "batch_id", length = 100)
    private String batchId;

    /**
     * 操作结果
     * <p>操作的执行结果。
     * 使用GradeOperationResult枚举管理所有操作结果</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "operation_result", length = 20)
    private GradeOperationResult operationResult = GradeOperationResult.SUCCESS;

    /**
     * 错误消息
     *
     * <p>操作失败时的错误信息。</p>
     */
    @Column(name = "error_message", columnDefinition = "TEXT")
    private String errorMessage;

    /**
     * 处理时间
     *
     * <p>操作处理的耗时（毫秒）。</p>
     */
    @Column(name = "processing_time_ms")
    private Long processingTimeMs;

    /**
     * 数据版本
     *
     * <p>操作时的数据版本号。</p>
     */
    @Column(name = "data_version", length = 20)
    private String dataVersion;

    /**
     * 操作状态
     * <p>操作执行时的状态。
     * 使用WorkflowStatus枚举管理所有操作状态</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "operation_status", length = 20)
    private WorkflowStatus operationStatus;

    /**
     * 关联任务ID
     *
     * <p>操作关联的任务ID。</p>
     */
    @Column(name = "related_task_id", length = 50)
    private String relatedTaskId;

    /**
     * 关联申请ID
     *
     * <p>操作关联的申请ID。</p>
     */
    @Column(name = "related_application_id", length = 50)
    private String relatedApplicationId;

    /**
     * 操作来源
     * <p>操作发起的来源。
     * 使用GradeOperationSource枚举管理所有操作来源</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "operation_source", length = 20)
    private GradeOperationSource operationSource = GradeOperationSource.WEB;

    /**
     * 影响记录数
     *
     * <p>操作影响的记录数量。</p>
     */
    @Column(name = "affected_records")
    private Integer affectedRecords;

    /**
     * 附件信息
     *
     * <p>操作相关的附件信息，JSON格式存储。</p>
     */
    @Column(name = "attachment_info", columnDefinition = "TEXT")
    private String attachmentInfo;

    /**
     * 扩展属性
     *
     * <p>操作的扩展属性，JSON格式存储。</p>
     */
    @Column(name = "extended_properties", columnDefinition = "TEXT")
    private String extendedProperties;

    /**
     * 日志级别
     * <p>日志记录的级别。
     * 使用GradeLogLevel枚举管理所有日志级别</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "log_level", length = 10)
    private GradeLogLevel logLevel = GradeLogLevel.INFO;

    /**
     * 是否关键操作
     *
     * <p>是否为关键业务操作。</p>
     */
    @Column(name = "is_critical", nullable = false)
    private Boolean isCritical = false;

    /**
     * 是否自动操作
     *
     * <p>是否为系统自动执行的操作。</p>
     */
    @Column(name = "is_automatic", nullable = false)
    private Boolean isAutomatic = false;

    /**
     * 父日志ID
     *
     * <p>父级日志记录的ID，用于操作链追踪。</p>
     */
    @Column(name = "parent_log_id")
    private Long parentLogId;

    /**
     * 操作序列号
     *
     * <p>在同一批次中的操作序列号。</p>
     */
    @Column(name = "sequence_number")
    private Integer sequenceNumber;

    // ===== 审计字段 =====

    /**
     * 创建时间
     */
    @CreatedDate
    @Column(name = "create_time", nullable = false, updatable = false)
    private LocalDateTime createTime;

    // ================================
    // 枚举迁移完成
    // ================================
    // - OperationType → GradeOperationType
    // - OperationResult → GradeOperationResult
    // - OperationSource → GradeOperationSource
    // - LogLevel → GradeLogLevel
    // - OperationStatus → WorkflowStatus (使用通用工作流状态枚举)
    // 所有枚举已实现BaseEnum接口并使用@Enumerated(EnumType.STRING)注解

}
